//////////////////////////////////////////////////////////////////////////
// xnserial类实现串口的物理管理
// 利用xnmq与xnanaly进行报文形式的交互。
//
//  CGL 2015-02-09 创建
//  

#ifndef XN_SERIAL_H
#define XN_SERIAL_H

#ifdef XNLINUX
#include <termios.h>
#endif

#ifdef XNLINUX
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#endif


#ifdef XNWIN
#include <windows.h>
#endif

#ifndef B0
// speed will be defined by termios.h, this is just for documentation
#define  B0       0000000  /* hang up */
#define  B50      0000001
#define  B75      0000002
#define  B110     0000003
#define  B134     0000004
#define  B150     0000005
#define  B200     0000006
#define  B300     0000007
#define  B600     0000010
#define  B1200    0000011
#define  B1800    0000012
#define  B2400    0000013
#define  B4800    0000014
#define  B9600    0000015
#define  B19200   0000016
#define  B38400   0000017
#define  B57600   0010001
#define  B115200  0010002
#define  B230400  0010003
#define  B460800  0010004
#define  B500000  0010005
#define  B576000  0010006
#define  B921600  0010007
#define  B1000000 0010010
#define  B1152000 0010011
#define  B1500000 0010012
#define  B2000000 0010013
#define  B2500000 0010014
#define  B3000000 0010015
#define  B3500000 0010016
#define  B4000000 0010017
#endif

class CXnSerial
{

public:
	enum Parity
    {
      NONE = 0,
      ODD ,
      EVEN
    };

public:
    CXnSerial();
    ~CXnSerial();

public:
    /**
    <pre>
    pDeviceName := /dev/ttyX (unix) | COMx (Windows) 
    iSpeed      := B50 ... B4000000                                    
    iBlock      := 0 | 1 (bool)    是否阻塞方式 在win下该参数无效                                      
    iRtscts     := 0 | 1 (bool)                                        
    iBits       := 7 | 8 (unix) | 4-8 (Windows)                        
    iStopBits   := 1 | 2                                               
    iParity     := CXnSerial::NONE | CXnSerial::ODD | CXnSerial::EVEN     
    return == 0  success, return < 0 error
    </pre>           
    */
    int openDevice(const char *pDeviceName, int iSpeed = B9600, int iBlock = 1, int iRtscts = 1, int iBits = 8, int iStopBits = 1, int iParity = CXnSerial::NONE);
	int openDeviceAgain(const char *pDeviceName);

	int closeDevice();    

    int readChar();
	int readBlock(unsigned char *pBuf, int iLen, int iTimeout = -1);

    int writeChar(unsigned char uchar);   
    int writeBlock(const unsigned char *pBuf, int iLen);

    int readLine(unsigned char *pBuf, int iMaxLen, int iTimeout = 1000);

private:
	int select(int iTimeout = 500); // 设置超时时间  返回0 超时，其他未超时

  private:
	  int m_iSpeed;
	  int m_iBlock;
	  int m_iRtscts;
	  int m_iBits;
	  int m_iStopBits;
	  int m_iParity;

#ifdef XNLINUX
    struct termios m_resetCommCfg; // 
	int m_fdSerial;
	struct timeval timout;
#endif

#ifdef XNWIN
    HANDLE m_hdlSerial;
#endif
};

#endif   // XN_SERIAL_H
